using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline.Processors;

using TInput = Microsoft.Xna.Framework.Content.Pipeline.Graphics.NodeContent;
using TOutput = Microsoft.Xna.Framework.Content.Pipeline.Processors.ModelContent;

namespace BoundingBoxModelExtension
{
    [ContentProcessor]
    public class ModelBoundingBoxProcessor : ModelProcessor
    {
        float minX = float.MaxValue;
        float minY = float.MaxValue;
        float minZ = float.MaxValue;
        float maxX = float.MinValue;
        float maxY = float.MinValue;
        float maxZ = float.MinValue; 

        public TOutput Process(TInput input, ContentProcessorContext context)
        {
            parseChildren(input.Children);

            ModelContent modelContent = base.Process(input, context);

            modelContent.Tag = new BoundingBox(new Vector3(minX, minY, minZ), new Vector3(maxX, maxY, maxZ));

            return modelContent;
        }

        private void parseChildren(NodeContentCollection nodeContentCollection)
        {
            foreach (NodeContent nodeContent in nodeContentCollection)
            {
                if (nodeContent is MeshContent)
                {
                    MeshContent meshContent = (MeshContent)nodeContent;
                    foreach (Vector3 vector in meshContent.Positions)
                    {
                        if (vector.X < minX)
                            minX = vector.X;

                        if (vector.Y < minY)
                            minY = vector.Y;

                        if (vector.Z < minZ)
                            minZ = vector.Z;

                        if (vector.X > maxX)
                            maxX = vector.X;

                        if (vector.Y > maxY)
                            maxY = vector.Y;

                        if (vector.Z > maxZ)
                            maxZ = vector.Z;
                    }
                }
                else
                {
                    parseChildren(nodeContent.Children);
                }
            }
        }
    }
}